package com.atguigu.tingshu.album.job;

import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author: atguigu
 * @create: 2024-08-17 14:10
 */
@Slf4j
@Component
public class RebuildBloomFilter {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    /**
     * 每月1号凌晨3点整重建布隆过滤器 cron表达式：0 0 3 * * ?
     * 测试每隔10s进行一次扩容
     */
    @Scheduled(cron = "0 0 2 1 * ?")
    public void rebuildBloomFilter() {
        log.info("重建布隆过滤器定时任务执行");
        //1.获取"旧"的布隆过滤器-获取现有数据量
        RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        long expectedInsertions = oldBloomFilter.getExpectedInsertions();
        long count = oldBloomFilter.count();
        double falseProbability = oldBloomFilter.getFalseProbability();
        //2.判断是否需要进行扩容，扩容条件：现有数量>期望数据规模
        if (count >= expectedInsertions) {
            //2.1 创建"新"的布隆过滤器完成初始化
            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
            newBloomFilter.tryInit(oldBloomFilter.getExpectedInsertions() * 2, falseProbability);
            //2.2 删除"旧"的布隆过滤器
            oldBloomFilter.delete();
            //2.3 再对新的布隆进行重命名：改回旧的名称
            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
            //3.查询专辑表得到最新库中审核通过的专辑ID列表
            LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AlbumInfo::getStatus, "0301");
            queryWrapper.select(AlbumInfo::getId);
            List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(queryWrapper);
            //4.将专辑ID加入到"新"的布隆过滤器
            if (CollectionUtil.isNotEmpty(albumInfoList)) {
                for (AlbumInfo albumInfo : albumInfoList) {
                    newBloomFilter.add(albumInfo.getId());
                }
            }
        }
    }
}